#ifndef CORE_H
#define CORE_H

#define clean_background(r, g, b) \
    glClearColor(r, g, b, 1.0f); \
    glClear(GL_COLOR_BUFFER_BIT); \

/* Create a empty buffer */
#define create_buffer(buffer_id) \
    unsigned int buffer_id = 0; \
    glGenBuffers(1, &buffer_id); \

/* Create a lot of empty buffer at once */
#define create_many_buffers(buffers_id_array, num) \
    unsigned int buffers_id_array[num]; \
    glGenBuffers(num, buffers_id_array); \

/* Bind to Vertex Array Buffer */
#define bind_to_vertex_buffer(target_buffer_id, verteice, size, dynamic) \
    glBindBuffer(GL_ARRAY_BUFFER, target_buffer_id); \
    glBufferData(GL_ARRAY_BUFFER, size, verteice, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); \
    glBindBuffer(GL_ARRAY_BUFFER, 0); \

/* Create many Vertex Array Objects at once */
#define create_many_vertex_array_objects(vertex_array_object_ids, num) \
    unsigned int vertex_array_object_ids[num]; \
    glGenVertexArrays(num, vertex_array_object_ids); \

/* 
 * Create a new Vertex Buffer Object 
 * 
 * Parameter:
 *      - vbo_id_name: Create Vertex Buffer Object id variate name
 *      - verteice: a OpenGL Vertex Array
 *      - size: memory size of verteice
 *      - dynamic: If true then the data is changed a lot and used many times(GL_STATIC_DRAW)
 */
#define create_vertex_buffer_object(vbo_id, verteice, dynamic, layout, group_size) \
    unsigned int vbo_id = 0;  \
    glGenBuffers(1, &vbo_id); \
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id); \
    glBufferData(GL_ARRAY_BUFFER, sizeof(verteice), verteice, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); \
    glVertexAttribPointer(layout, group_size, GL_FLOAT, GL_FALSE, group_size * sizeof(float), (void*)0); \
    glEnableVertexAttribArray(layout); \

/*
 * Enable Vertex Buffer Object
 * 
 * Parameter:
 *      - vertex_buffer_object_id: The vao id you want to enable
 */
#define enable_vertex_buffer(vertex_buffer_object_id) glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object_id)

/*
 * Disable Vertex Buffer Object (glBindBuffer(GL_ARRAY_BUFFER, 0);)
 */
#define disable_vertex_buffer() glBindBuffer(GL_ARRAY_BUFFER, 0)


/*
 * Delete Vertex Buffer Object
 * 
 * Parameter: 
 *      - vertex_buffer_object_id: The vbo id you want to delete
 */
#define delete_vertex_buffer_object(vertex_buffer_object_id) glDeleteBuffers(1, &vertex_buffer_object_id)

/* Delete many Vertex Buffer Objects at once */
#define delete_many_vertex_buffer_objects(vertex_buffer_object_ids, num) glDeleteBuffers(num, vertex_buffer_object_ids)
/*
 * Create Element Buffer Object 
 *
 * Parameter:
 *      - ebo_id_name: Create Element Buffer Object id variate name
 *      - indices: To used indices
 *      - size: memory size of indices
 *      - dynamic: If true then the data is changed a lot and used many times(GL_STATIC_DRAW)
 */
#define create_element_buffer_object(ebo_id, indices, dynamic) \
    unsigned int ebo_id = 0; \
    glGenBuffers(1, &ebo_id); \
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_id); \
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, dynamic? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); \
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_id); \

/* 
 * Enable Element Buffer Object 
 *
 * Parameter:
 *      element_buffer_object_id: The ebo id you want to enable
 */
#define enable_element_buffer(element_buffer_object_id) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_object_id)

/* 
 * Disable Element Buffer Object (glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0))
 */
#define disable_element_buffer() glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)

/*
 * Delete Element Buffer Object 
 * 
 * Parameter:
 *      element_buffer_object_id: The ebo id you want to delete
 */
#define delete_element_buffer(element_buffer_object_id) glDeleteBuffers(1, &element_buffer_object_id)

/* 
 * Create a new Vertex Array Object
 *
 *  Parameter:
 *      - vao_id: Create Vertex Array Object id variate name
 */
#define create_vertex_array_object(vao_id) \
    unsigned int vao_id = 0; \
    glGenVertexArrays(1, &vao_id); \
    glBindVertexArray(vao_id); \

/*
 * Enable Vertex Array Object
 * 
 * Parameter:
 *      - vertex_array_object_id: The vao id you want to enable
 */
#define enable_vertex_array(vertex_array_object_id) glBindVertexArray(vertex_array_object_id)

/*
 * Disable Vertex Array Object
 */
#define disable_vertex_array() glBindBuffer(GL_ARRAY_BUFFER, 0)

/*
 * Delete Vertex Buffer Object
 *
 * Parameter: 
 *      - vertex_buffer_object_id: The vbo id that you want to delete
 */
#define delete_vertex_array_object(vertex_array_object_id) glDeleteVertexArrays(1, &vertex_array_object_id)

/* delete many VAOs at once */
#define delete_many_vertex_array_objects(vertex_array_object_ids, num) glDeleteVertexArrays(num, vertex_array_object_ids)


#endif /* CORE_H END */